package com.tiny.mirror.service.product.application.query;

import com.api.tiny.mirror.service.product.request.PageAppRequest;
import com.api.tiny.mirror.service.product.request.ParamsRequest;
import com.api.tiny.mirror.service.product.response.AppVO;
import com.api.tiny.mirror.service.product.response.DashboardPlatformDetailVO;
import com.api.tiny.mirror.service.product.response.ShoppingAppDetailVO;
import com.api.tiny.mirror.service.product.response.ShoppingAppVO;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.tiny.mirror.basic.common.code.CommonStatusCode;
import com.tiny.mirror.basic.web.dto.response.BasePageResponse;
import com.tiny.mirror.basic.web.exception.BusinessException;
import com.tiny.mirror.service.product.application.convert.AppConvert;
import com.tiny.mirror.service.product.application.convert.PlatformConvert;
import com.tiny.mirror.service.product.common.constants.ProductStatusCode;
import com.tiny.mirror.service.product.enums.AppStatusEnum;
import com.tiny.mirror.service.product.enums.AppTypeEnum;
import com.tiny.mirror.service.product.enums.PlatformStatusEnum;
import com.tiny.mirror.service.product.infrastructure.entity.db.AbilityEntity;
import com.tiny.mirror.service.product.infrastructure.entity.db.AppEntity;
import com.tiny.mirror.service.product.infrastructure.entity.db.PlatformAbilityRelEntity;
import com.tiny.mirror.service.product.infrastructure.entity.db.PlatformEntity;
import com.tiny.mirror.service.product.infrastructure.repository.db.AbilityMapper;
import com.tiny.mirror.service.product.infrastructure.repository.db.AppMapper;
import com.tiny.mirror.service.product.infrastructure.repository.db.PlatformAbilityRelMapper;
import com.tiny.mirror.service.product.infrastructure.repository.db.PlatformMapper;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
import javax.annotation.Resource;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

/**
 * @Author: liujsh
 * @Description:
 * @Date: Create in 2023/9/27
 */
@Service
public class AppQryService {

  @Resource
  private AppMapper appMapper;
  @Resource
  private PlatformMapper platformMapper;
  @Resource
  private PlatformAbilityRelMapper platformAbilityRelMapper;
  @Resource
  private AbilityMapper abilityMapper;

  public BasePageResponse<AppVO> page(PageAppRequest request) {
    QueryWrapper<AppEntity> queryWrapper = new QueryWrapper<>();
    String name = request.getName();
    if (StringUtils.isNotBlank(name)) {
      queryWrapper.lambda().like(AppEntity::getName, name);
    }
    AppTypeEnum type = request.getType();
    if (type != null) {
      queryWrapper.lambda().like(AppEntity::getType, type);
    }
    AppStatusEnum status = request.getStatus();
    if (status != null) {
      queryWrapper.lambda().eq(AppEntity::getStatus, status);
    }
    ParamsRequest params = request.getParams();
    if (params != null) {
      if (params.getBeginCreateTime() != null) {
        queryWrapper.lambda().ge(AppEntity::getCreateTime, params.getBeginCreateTime());
      }
      if (params.getEndCreateTime() != null) {
        queryWrapper.lambda().le(AppEntity::getCreateTime, params.getEndCreateTime());
      }
      if (params.getBeginUpdateTime() != null) {
        queryWrapper.lambda().ge(AppEntity::getUpdateTime, params.getBeginUpdateTime());
      }
      if (params.getEndUpdateTime() != null) {
        queryWrapper.lambda().le(AppEntity::getUpdateTime, params.getEndUpdateTime());
      }
    }
    IPage<AppEntity> iPage = appMapper.selectPage(
        new Page<>(request.getPage(), request.getPageSize()), queryWrapper
    );
    List<AppVO> list = AppConvert.convertEntityListToAppVOList(iPage.getRecords());
    if (CollectionUtils.isNotEmpty(list)) {
      for (AppVO entity : list) {
        QueryWrapper<PlatformEntity> platformQueryWrapper = new QueryWrapper<>();
        Long count = platformMapper.selectCount(platformQueryWrapper);
        entity.setPlatformNum(count);
      }
    }
    return BasePageResponse.success(
        iPage.getPages(), iPage.getSize(),
        list,
        iPage.getTotal()
    );
  }

  public AppVO getInfo(Long id) {
    AppEntity entity = appMapper.selectById(id);
    if (Objects.isNull(entity)) {
      throw new BusinessException(CommonStatusCode.DATA_NOT_EXIST.args("app:" + id));
    }
    return AppConvert.convertToAppVO(entity);
  }

  public BasePageResponse<ShoppingAppVO> pageDashboardApp() {
    QueryWrapper<AppEntity> queryWrapper = new QueryWrapper<>();
    queryWrapper.lambda().eq(AppEntity::getStatus, AppStatusEnum.ABLE)
        .orderByAsc(AppEntity::getOrderNum);
    IPage<AppEntity> iPage = appMapper.selectPage(
        new Page<>(1, 10), queryWrapper
    );
    List<ShoppingAppVO> list = AppConvert.convertEntityListToDashboardAppVOList(
        iPage.getRecords()
    );
    if (CollectionUtils.isNotEmpty(list)) {
      for (ShoppingAppVO vo : list) {
        QueryWrapper<PlatformEntity> platformQueryWrapper = new QueryWrapper<>();
        platformQueryWrapper.lambda().eq(PlatformEntity::getAppId, vo.getId())
            .eq(PlatformEntity::getStatus, PlatformStatusEnum.ABLE)
            .orderByAsc(PlatformEntity::getOrderNum);
        List<PlatformEntity> platformList = platformMapper.selectList(platformQueryWrapper);
        if (CollectionUtils.isNotEmpty(platformList)) {
          vo.setPlatformTypeList(
              platformList.stream().map(p -> p.getType()).collect(Collectors.toList())
          );
        }
      }
    }
    return BasePageResponse.success(
        iPage.getPages(), iPage.getSize(),
        list,
        iPage.getTotal()
    );
  }

  public ShoppingAppDetailVO getDashboardAppDetail(Long id) {
    QueryWrapper<AppEntity> queryWrapper = new QueryWrapper<>();
    queryWrapper.lambda().eq(AppEntity::getId, id).eq(AppEntity::getStatus, AppStatusEnum.ABLE);
    AppEntity entity = appMapper.selectOne(queryWrapper);
    if (entity == null) {
      return null;
    }
    ShoppingAppDetailVO appDetailVO = AppConvert.convertToDashboardAppDetailVO(entity);
    QueryWrapper<PlatformEntity> platformQueryWrapper = new QueryWrapper<>();
    platformQueryWrapper.lambda().eq(PlatformEntity::getAppId, id)
        .eq(PlatformEntity::getStatus, PlatformStatusEnum.ABLE)
        .orderByAsc(PlatformEntity::getOrderNum);
    List<PlatformEntity> platformList = platformMapper.selectList(platformQueryWrapper);
    if (CollectionUtils.isEmpty(platformList)) {
      return appDetailVO;
    }
    List<DashboardPlatformDetailVO> platformVOList
        = PlatformConvert.convertEntityListToDashboardPlatformDetailVOList(platformList);
    for (DashboardPlatformDetailVO platformDetailVO : platformVOList) {
      Long platformId = platformDetailVO.getId();
      List<PlatformAbilityRelEntity> relList
          = platformAbilityRelMapper.selectByPlatformId(platformId);
      if (CollectionUtils.isNotEmpty(relList)) {
        List<Long> abilityIds = relList.stream().map(r -> r.getAbilityId())
            .collect(Collectors.toList());
        QueryWrapper<AbilityEntity> abilityQueryWrapper = new QueryWrapper<>();
        abilityQueryWrapper.lambda().eq(AbilityEntity::getId, abilityIds)
            .select(AbilityEntity::getName)
            .orderByAsc(AbilityEntity::getOrderNum);
        List<String> abilityNameList = abilityMapper.selectList(abilityQueryWrapper)
            .stream().map(a -> a.getName()).collect(Collectors.toList());
        platformDetailVO.setAbilityDetail(
            String.join(",", abilityNameList)
        );
      }
    }
    appDetailVO.setPlatformList(platformVOList);
    return appDetailVO;
  }

  public void checkCreateApp(AppTypeEnum type) {
    QueryWrapper<AppEntity> queryWrapper = new QueryWrapper<>();
    queryWrapper.lambda().eq(AppEntity::getType, type);
    long count = appMapper.selectCount(queryWrapper);
    if (count > 0) {
      throw new BusinessException(ProductStatusCode.CREATE_APP_ERROR_EXIST_TYPE);
    }
  }
}
